local config=require("config.application")
local utils = require "vanilla.v.libs.utils"
local json = require "library.dkjson"
local db = require "models.db"
local base64encode=ngx.encode_base64
local base64decode=ngx.decode_base64
local  helpers = {}


--内部调用
function helpers:config_get(key)
    local config = require ('library.config'):new()
    return config:get(key)
end

--内部调用
function helpers:no_cache(url,params,get_params)
    params=params or {}
    params['url']=self:url(url,get_params)
    db:replace_data(params,json.null)
    params=base64encode(json.encode(params))
    return '<!--[no_cache '..params..']-->'
end


--不缓存的替换
function helpers:no_cache_replace(content)
    local iterator,err =ngx.re.gmatch(content,"<!--\\[no_cache ([a-zA-Z0-9/+=]*)\\]-->",'i')
    local params={}
    local urls={}
    if iterator then
        while true do
            local m=iterator() 
            if not m then
                break
            end
            if not params[m[1]] then
                local param=json.decode(base64decode(m[1]))
                urls[#urls+1]={param['url'],{method = ngx.HTTP_POST, body = ngx.encode_args(param)}}
                params[m[1]]=#urls
            end
        end
    end

    if not self:is_empty_table(urls) then
        ngx.req.set_header("Content-Type", "text/html")
        local responses={ngx.location.capture_multi(urls)}
        content=ngx.re.gsub(content,"<!--\\[no_cache ([a-zA-Z0-9/+=]*)\\]-->",function(m)
            --这里面不能使用ngx.location.capture
            local index=params[m[1]]
            if responses[index] and responses[index].status== ngx.HTTP_OK then
                return responses[index].body
            end
            return responses[index].body
        end)
    end


    return content
end

function helpers:is_numeric(str)
	local  m = ngx.re.match(str,"^[\\-+]?[0-9]*\\.?[0-9]+$")
	if m then
		return true
	end
	return false
end

function helpers:is_int( str )
	local  m = ngx.re.match(str,"^[\\-+]?[0-9]+$")
	if m then
		return true
	end
	return false
end

function helpers:is_natural( str )
    str=tostring(str)
	local  m = ngx.re.match(str,"^[0-9]+$")
	if m then
		return true
	end
	return false
end

function helpers:is_natural_no_zero( str )
    str=tostring(str)
	if str~='0' and self:is_natural(str) then
		return true
	end

	return false
end

function helpers:sha1(str)
	local mysa1=require ('resty.sha1').new()
	mysa1:update(str)
	local restr= mysa1:final()
	local tableval={}
	for i=1,#restr do
		tableval[#tableval+1]=string.format('%02x',string.byte(restr,i))
	end
	mysa1:reset()

	return table.concat( tableval, "" )
end

function helpers:show_msg(code,msg,data)
    if self:is_ajax() then
        return json.encode({
            code=code,
            msg=msg,
            data=data,
        })
    end
    local url=data['url']
    local time=data['time']
    local sys_statck=require('vanilla.v.ctxstatck'):sys_statck()
	time=time or 1
	local dispatch=sys_statck:get()
	local table={['url']=url,['msg']=msg,['time']=time}
	return dispatch.view:render('msg.html',table)
end

function helpers:is_ajax()
    return ngx.req.get_headers()['X-Requested-With']=='XMLHttpRequest'
end

function helpers:get_session()
    local sys_statck=require('vanilla.v.ctxstatck'):sys_statck()
	local dispatch=sys_statck:get();
	return  dispatch.session;
end

function helpers:split(s, delim)
    if type(delim) ~= "string" or string.len(delim) <= 0 then
        return
    end

    local start = 1
    local t = {}
    while true do
    local pos = string.find (s, delim, start, true) -- plain find
        if not pos then
          break
        end

        table.insert (t, string.sub (s, start, pos - 1))
        start = pos + string.len (delim)
    end
    table.insert (t, string.sub (s, start))

    return t
end


function helpers:url(path,params)
	if type(params) == "table" then
		return config.site_url..path.."?"..self:http_bilud(params)
	else
		return config.site_url..path
	end
end

function helpers:http_bilud(params)
	params=params or {}
	local new={}
	for k,v in pairs(params) do
		new[#new+1]=k.."="..ngx.escape_uri(v) 
	end
	return table.concat(new,'&')
end

function helpers:run(path,params)
	params=params or {}
	local res = ngx.location.capture(path,{args=params,ctx=ngx.ctx})
	return res.body
end


function helpers:raise_syserror(error)
    local sys_statck=require('vanilla.v.ctxstatck'):sys_statck()
    sys_statck:get():errResponse({code=1000, msg={["msg"]=error}});
end

function helpers:is_empty_table(table)
    if not table or _G.next(table)==nil then
        return true
    end
    return false
end

function helpers:in_table(val,table)
    if not table then
        self:raise_syserror("in_table is not table")
    end

    if not val then
        return false
    end

    for k,v in pairs(table) do
        if  v==val then
            return true
        end
    end

    return false;
end

function helpers:table_key_exist(val,table)
    if not table then
        self:raise_syserror("in_table is not table")
    end

    if not val then
        return false
    end

    for k,v in pairs(table) do
        if  k==val then
            return true
        end
    end

    return false;
end

function helpers:is_table(table)
    return table and type(table)=='table'
end


function helpers:substr(string,length,etc)
	etc=etc or "..."
	return string.sub(string,0,length)..etc
end

function helpers:strip_tag(str)
	return ngx.re.gsub(str,"<[^>]*>","")
end 


--@brief 切割字符串，并用“...”替换尾部
--@param sName:要切割的字符串
--@return nMaxCount，字符串上限,中文字为2的倍数
--@param nShowCount：显示英文字个数，中文字为2的倍数,可为空
--@note         函数实现：截取字符串一部分，剩余用“...”替换
function helpers:substr_utf8(sName,nMaxCount,nShowCount)
    if sName == nil or nMaxCount == nil then
        return
    end
    local sStr = sName
    local tCode = {}
    local tName = {}
    local nLenInByte = #sStr
    local nWidth = 0
    if nShowCount == nil then
       nShowCount = nMaxCount - 3
    end
    for i=1,nLenInByte do
        local curByte = string.byte(sStr, i)
        local byteCount = 0;
        if curByte>0 and curByte<=127 then
            byteCount = 1
        elseif curByte>=192 and curByte<223 then
            byteCount = 2
        elseif curByte>=224 and curByte<239 then
            byteCount = 3
        elseif curByte>=240 and curByte<=247 then
            byteCount = 4
        end
        local char = nil
        if byteCount > 0 then
            char = string.sub(sStr, i, i+byteCount-1)
            i = i + byteCount -1
        end
        if byteCount == 1 then
            nWidth = nWidth + 1
            table.insert(tName,char)
            table.insert(tCode,1)
            
        elseif byteCount > 1 then
            nWidth = nWidth + 2
            table.insert(tName,char)
            table.insert(tCode,2)
        end
    end
    
    if nWidth > nMaxCount then
        local _sN = ""
        local _len = 0
        for i=1,#tName do
            _sN = _sN .. tName[i]
            _len = _len + tCode[i]
            if _len >= nShowCount then
                break
            end
        end
        sName = _sN .. "..."
    end
    return sName
end

--@brief 字符串长度,中文是1,英文也是1
--@param sName:要切割的字符串
function helpers:mbstr_len_utf8(sName)
    if not sName then
        return 0
    end
    local sStr = sName
    local nLenInByte = #sStr
    local nWidth = 0

    for i=1,nLenInByte do
        local curByte = string.byte(sStr, i)
        local byteCount = 0;
        if curByte>0 and curByte<=127 then
            byteCount = 1
        elseif curByte>=192 and curByte<223 then
            byteCount = 2
        elseif curByte>=224 and curByte<239 then
            byteCount = 3
        elseif curByte>=240 and curByte<=247 then
            byteCount = 4
        end
        if byteCount > 0 then
            i = i + byteCount -1
            nWidth=nWidth+1
        end
    end
    return nWidth
end

function helpers:ltrim(str,charlist)
    charlist =charlist or " \t\n\r"
    return string.gsub(str, "^["..charlist.."]+", "")
end

function helpers:rtrim(str,charlist)
    charlist =charlist or " \t\n\r"
    return string.gsub(str, "["..charlist.."]+$", "")
end

function helpers:trim(str,charlist)
    str = self:ltrim(str,charlist)
    return self:rtrim(str,charlist)
end

function helpers:ucfirst(str)
    return string.upper(string.sub(str, 1, 1)) .. string.sub(str, 2)
end

function helpers:intval(str)
    local n=tonumber(str)
    if n then
        return n
    end
    return 0
end


return helpers